package es.eupt.amazingpi.server.threads;

import java.net.Socket;
import java.net.SocketException;

import es.eupt.amazingpi.model.juego.MensajeJuego;
import es.eupt.amazingpi.model.usuario.MensajeUsuario;
import es.eupt.amazingpi.model.usuario.Usuario;
import es.eupt.amazingpi.server.gestion.GestionServer;
import es.eupt.amazingpi.server.gestion.GestionUsuario;
import es.eupt.amazingpi.sync.Mensaje;
import es.eupt.amazingpi.sync.MensajeInputStream;
import es.eupt.amazingpi.sync.MensajeOutputStream;
import es.eupt.amazingpi.sync.Pi;
import es.eupt.amazingpi.sync.ResponseMessage;

public class HiloUsuario extends Thread {

	private Usuario usuario;
	Pi pi;
	MensajeOutputStream salida;
	MensajeInputStream entrada;
	Socket socket;
	GestionServer server;
	GestionUsuario gestionUsuario;
	HiloJuego hiloJuego;
	boolean finalize = false;

	public HiloUsuario(){}
	
	public HiloUsuario(Usuario usuario, Socket socket, MensajeInputStream entrada, MensajeOutputStream salida) {
		this.usuario = usuario;
		this.socket = socket;
		this.entrada = entrada;
		this.salida = salida;
//		gestionUsuario = new GestionUsuario(usuario);
	}
	
	public void setServer(GestionServer server) {
		this.server = server;
	}

	@Override
	public void run() {
		esperarMensajes();
	}
	
	public void esperarMensajes(){
		while(true) {
			if (finalize){
				break;
			}
			try{
				trace("Esperando mensajes");
				Mensaje mensaje = entrada.readMensaje();
				procesarMensaje(mensaje);
			} catch (SocketException e) {
				server.desconectarUsuario(usuario.getNombre());
				break;
			}catch(Exception e){
				break;
			}
		}
		System.out.println("HILO USUARIO: Hilo finalizado");
	}
	
	public void escribir(Mensaje mensaje) {
		try{
			trace("Voy a escribir el mensaje a mi usuario: " + mensaje);
			salida.writeMensaje(mensaje);
		}catch(Exception e){
			
		}
	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}
	
	private void procesarMensaje(Mensaje mensaje){
		
		try {
			if (mensaje instanceof MensajeUsuario) {
				MensajeUsuario msj = (MensajeUsuario)mensaje;
				if (msj.esDesconexion()){
					server.desconectarUsuario(usuario.getNombre());
					entrada.close();
					salida.close();
					finalize = true;
				} else if (msj.esTexto()){
//					server.enviarMensajeATodos(msj, msj.getEmisor());
				} else if (msj.esIniciarJuego()){
//					server.iniciarJuego(usuario.getNombre(), msj.getReceptor());
				} else if (msj.esAgregarAmigo()){
					agregarAmigo(msj);
				} else if (msj.esBuscarUsuario()){
					buscarUsuarios(msj);
				} else if (msj.esCrearPartida()){
					crearPartida(msj);
				} else {
					trace("Mensaje desconocido: " + msj.getCodigo());
				}
			} else if (mensaje instanceof MensajeJuego){
				MensajeJuego msj = (MensajeJuego)mensaje;
				if (msj.esFicha()){
					
				} else if (msj.esFichaResuelta()){
					
				} else if (msj.esLiberarPi()){
				
				} else if (msj.esMeRindo()){
					
				} else if (msj.esNotificarPi()){
					
				} else if (msj.esPi()) {
					hiloJuego.pi(usuario.getNombre());
				} else if (msj.esSoluciones()){
					
				} else {
					
				}
			}
		} catch (Exception e) {
			trace("El mensaje no se ha podido procesar");
		}
	}
	
	private void agregarAmigo(MensajeUsuario msj){
		ResponseMessage response = new ResponseMessage();
//		response = gestionUsuario.agregarAmigo(msj.getReceptor());
		if (response.isError){
			msj = new MensajeUsuario();
			msj.setCodigo(Mensaje.CODIGO_ERROR);
			msj.setTexto(response.getMessage());
		} else {
			msj = new MensajeUsuario();
			msj.setCodigo(MensajeUsuario.CODIGO_AGREGAR_AMIGO);
		}
		escribir(msj);
	}
	
	private void buscarUsuarios(MensajeUsuario msj){
		ResponseMessage response = new ResponseMessage();
		response = gestionUsuario.buscarUsuarios(msj.getTexto());
		if (response.isError){
			msj = new MensajeUsuario();
			msj.setCodigo(Mensaje.CODIGO_ERROR);
			msj.setTexto(response.getMessage());
		} else {
			msj = new MensajeUsuario();
			msj.setCodigo(MensajeUsuario.CODIGO_BUSCAR_USUARIO);
		}
		escribir(msj);
	}
	
	private void crearPartida(MensajeUsuario msj){
		ResponseMessage response = new ResponseMessage();
//		response = gestionUsuario.crearPartida(msj.getTexto(), msj.getTipoPartida());
		if (response.isError){
			msj = new MensajeUsuario();
			msj.setCodigo(Mensaje.CODIGO_ERROR);
			msj.setTexto(response.getMessage());
		} else {
			msj = new MensajeUsuario();
			msj.setCodigo(MensajeUsuario.CODIGO_CREARPARTIDA);
		}
		escribir(msj);
	}
	
	private void trace(String msg){
		System.out.println("HILO USUARIO ["+usuario.getNombre()+"]>> " + msg);
	}
	
	public void iniciarJuego(HiloJuego hiloJuego){
		this.hiloJuego = hiloJuego;
		MensajeUsuario mensaje = new MensajeUsuario();
		mensaje.setCodigo(MensajeUsuario.CODIGO_INICIAR_JUEGO);
		escribir(mensaje);
		System.out.println("El usuario se ha unido a un juego");
	}
}
